package com.iwithlong.utils;

import com.chenlb.mmseg4j.analysis.ComplexAnalyzer;
import com.iwithlong.context.Constants;
import com.iwithlong.enums.IndexType;
import com.iwithlong.vo.ActivityAreaVo;
import com.iwithlong.vo.ActivityVo;
import com.ktanx.platform.setting.kit.SettingKit;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 索引工具
 * <p>
 * User: TJM
 * Date: 2017/10/16 16:36
 * version $Id: IndexUtils.java, v 0.1  16:36 Exp $
 */
public class IndexUtils {

	/**
	 * 活动 转 索引存储对象
	 * @param activityVo
	 * @return
	 */
	public static Document activity2Doc (ActivityVo activityVo){

		Document document=new Document ();


		document.add (new Field ("activityId",activityVo.getActivityId ()+ IndexType.ACTIVITY.getCode (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new NumericField ("activityAreaId", Field.Store.YES,true).setLongValue (activityVo.getActivityAreaId ()));
		document.add (new Field ("name",activityVo.getName (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("brief",activityVo.getBrief (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("content",activityVo.getContent (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("status",activityVo.getStatus (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("firstPicUrl",activityVo.getFirstPicUrl(),Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("enable",String.valueOf(activityVo.isEnable ()), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new NumericField ("numberOfClick", Field.Store.YES,true).setLongValue (activityVo.getNumberOfClick ()));
		document.add (new NumericField ("numberOfInterest", Field.Store.YES,true).setLongValue (activityVo.getNumberOfInterest ()));
		document.add (new NumericField ("recommended", Field.Store.YES,true).setLongValue (activityVo.getRecommended ()));


		document.add (new NumericField ("beginDate", Field.Store.YES,true).setLongValue (activityVo.getBeginDate ().getTime ()));
		document.add (new NumericField ("endDate", Field.Store.YES,true).setLongValue (activityVo.getEndDate ().getTime ()));
		document.add (new NumericField ("gmtIssue", Field.Store.YES,true).setLongValue (activityVo.getGmtIssue ().getTime ()));


		document.add (new Field ("activityLabel",String.valueOf(activityVo.getActivityLabel ()), Field.Store.YES,Field.Index.ANALYZED));


		Double weight=getWeight (activityVo.getNumberOfClick (),activityVo.getNumberOfInterest (),activityVo.getRecommended ());
		document.add (new NumericField ("weight", Field.Store.YES,true).setDoubleValue (weight));


		document.add (new NumericField ("latitude", Field.Store.YES,true).setDoubleValue (activityVo.getLatitude ()));
		document.add (new NumericField ("longitude", Field.Store.YES,true).setDoubleValue (activityVo.getLongitude ()));


		document.add (new Field ("indexType",IndexType.ACTIVITY.getCode (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));

		document.add (new Field ("activityAreaStatus",activityVo.getActivityAreaStatus (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("activityAreaEnable",String.valueOf(activityVo.isActivityAreaEnable ()), Field.Store.YES,Field.Index.ANALYZED));


		document.add (new Field ("weixinStrs",activityVo.getWeixinStrs (), Field.Store.YES,Field.Index.ANALYZED));

		return document;
	}


	/**
	 * 获取权重
	 * @param numberOfClick
	 * @param numberOfInterest
	 * @param recommended
	 * @return
	 */
	public static Double getWeight(Long numberOfClick,Long numberOfInterest,Long recommended ){

		//权重系数=numberOfClick*X+numberOfInterest*Y+recommended*Z


		//阅数量系数
		String x = SettingKit.getValue (Constants.NUMBER_OF_CLICK_COEFFICIENT);
		Double aDouble = Double.valueOf (x);
		if (numberOfClick==null) {
			numberOfClick=0L;
		}

		//兴趣量系数
		String y = SettingKit.getValue (Constants.NUMBER_OF_INTEREST_COEFFICIENT);
		Double bDouble = Double.valueOf (y);
		if (numberOfInterest==null) {
			numberOfInterest=0L;
		}

		//推荐度系数
		String z = SettingKit.getValue (Constants.RECOMMENDED_COEFFICIENT);
		Double cDouble = Double.valueOf (z);
		if (recommended==null) {
			recommended=0L;
		}else if(recommended==5){
			return Double.MAX_VALUE;
		}


		return aDouble*numberOfClick+bDouble*numberOfInterest+cDouble*recommended;
	}

	/**
	 * 活动列表 转 索引列表
	 * @param activityList
	 * @return
	 */
	public static List<Document> activityList2Docs(List<ActivityVo> activityList){
		List<Document> documentList=new ArrayList<> ();
		for (ActivityVo activityVo : activityList) {
			Document document = activity2Doc (activityVo);
			documentList.add (document);

		}
		return documentList;
	}

	/**
	 * 索引 转 活动
	 * @param document
	 * @return
	 */
	public static ActivityVo doc2Activity (Document document){

		ActivityVo activityVo=new ActivityVo ();

		String activityId = document.get ("activityId").replace (IndexType.ACTIVITY.getCode (),"");

		activityVo.setActivityId (Long.valueOf (activityId));
		activityVo.setActivityAreaId (Long.valueOf (document.get ("activityAreaId")));
		activityVo.setName (document.get ("name"));
		activityVo.setBrief (document.get ("brief"));
		activityVo.setContent (document.get ("content"));
		activityVo.setStatus (document.get ("status"));
		activityVo.setNumberOfClick (Long.valueOf (document.get ("numberOfClick")));
		activityVo.setNumberOfInterest (Long.valueOf (document.get ("numberOfInterest")));
		activityVo.setRecommended (Long.valueOf (document.get ("recommended")));
		activityVo.setFirstPicUrl(document.get("firstPicUrl"));
		activityVo.setEnable(StringUtils.equals(document.get("enable"),"true"));

		activityVo.setBeginDate (new Date (Long.valueOf (document.get ("beginDate"))));
		activityVo.setEndDate (new Date (Long.valueOf (document.get ("endDate"))));
		activityVo.setGmtIssue (new Date (Long.valueOf (document.get ("gmtIssue"))));

		activityVo.setActivityLabel (document.get ("activityLabel"));

		activityVo.setLatitude (Double.valueOf (document.get ("latitude")));
		activityVo.setLongitude (Double.valueOf (document.get ("longitude")));

		activityVo.setActivityAreaStatus (document.get ("activityAreaStatus"));
		activityVo.setActivityAreaEnable (StringUtils.equals(document.get("activityAreaEnable"),"true"));
		activityVo.setWeight(Double.valueOf (document.get ("weight")));
		activityVo.setWeixinStrs (document.get ("weixinStrs"));
		return activityVo;
	}

	/**
	 * 索引列表 转 活动列表
	 * @param documentList
	 * @return
	 */
	public static List<ActivityVo> docs2ActivityList(List<Document> documentList){
		List<ActivityVo> activityVoList=new ArrayList<> ();
		for (Document document : documentList) {
			ActivityVo activityVo = doc2Activity (document);
			activityVoList.add (activityVo);
		}
		return activityVoList;
	}

	/**
	 * 活动点 转  索引
	 * @param activityAreaVo
	 * @return
	 */
	public static Document activityArea2Doc (ActivityAreaVo activityAreaVo){
		Document document=new Document ();

		document.add (new Field ("activityAreaId",activityAreaVo.getActivityAreaId ()+ IndexType.ACTIVITY_AREA.getCode (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("areaName",activityAreaVo.getAreaName (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("brief",activityAreaVo.getBrief (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("areaIntroduction",activityAreaVo.getAreaIntroduction (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("address",activityAreaVo.getAddress (), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("province",activityAreaVo.getProvince (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("city",activityAreaVo.getCity (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("district",activityAreaVo.getDistrict (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("status",activityAreaVo.getStatus (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new Field ("enable",String.valueOf(activityAreaVo.isEnable ()), Field.Store.YES,Field.Index.ANALYZED));
		document.add (new Field ("firstPicUrl",activityAreaVo.getFirstPicUrl(),Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
		document.add (new NumericField ("latitude", Field.Store.YES,true).setDoubleValue (activityAreaVo.getLatitude ()));
		document.add (new NumericField ("longitude", Field.Store.YES,true).setDoubleValue (activityAreaVo.getLongitude ()));
		document.add (new NumericField ("gmtIssue", Field.Store.YES,true).setLongValue (activityAreaVo.getGmtIssue ().getTime ()));


		document.add (new Field ("indexType",IndexType.ACTIVITY_AREA.getCode (), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));

		return document;
	}

	/**
	 * 活动点列表 转 索引列表
	 * @param activityVoAreaList
	 * @return
	 */
	public static List<Document> activityAreaList2Docs(List<ActivityAreaVo> activityVoAreaList){
		List<Document> documentList=new ArrayList<> ();
		for (ActivityAreaVo activityAreaVo : activityVoAreaList) {
			Document document = activityArea2Doc (activityAreaVo);
			documentList.add (document);
		}
		return documentList;
	}

	/**
	 * 索引 转 活动点
	 * @param document
	 * @return
	 */
	public static ActivityAreaVo doc2ActivityArea(Document document){

		ActivityAreaVo activityAreaVo=new ActivityAreaVo ();

		String activityAreaId = document.get ("activityAreaId").replace (IndexType.ACTIVITY_AREA.getCode (), "");

		activityAreaVo.setActivityAreaId (Long.valueOf (activityAreaId));
		activityAreaVo.setAreaName (document.get ("areaName"));
		activityAreaVo.setBrief (document.get ("brief"));
		activityAreaVo.setAreaIntroduction (document.get ("areaIntroduction"));
		activityAreaVo.setAddress (document.get ("address"));
		activityAreaVo.setProvince (document.get ("province"));
		activityAreaVo.setCity (document.get ("city"));
		activityAreaVo.setDistrict (document.get ("district"));
		activityAreaVo.setStatus (document.get ("status"));
		activityAreaVo.setFirstPicUrl(document.get("firstPicUrl"));
		activityAreaVo.setEnable(StringUtils.equals(document.get("enable"),"true"));
		activityAreaVo.setLatitude (Double.valueOf (document.get ("latitude")));
		activityAreaVo.setLongitude (Double.valueOf (document.get ("longitude")));
		activityAreaVo.setTitle(activityAreaVo.getAreaName());
		activityAreaVo.setGmtIssue (new Date (Long.valueOf (document.get ("gmtIssue"))));
		return activityAreaVo;
	}

	/**
	 * 索引列表 转 活动点列表
	 * @param documentList
	 * @return
	 */
	public static List<ActivityAreaVo> docs2ActivityAreaList(List<Document> documentList){
		List<ActivityAreaVo> activityAreaVoList=new ArrayList<> ();
		long i=0L;
		for (Document document : documentList) {
			ActivityAreaVo activityAreaVo = doc2ActivityArea (document);
			activityAreaVo.setId(i);
			activityAreaVoList.add (activityAreaVo);
			i++;
		}
		return activityAreaVoList;
	}


	/**
	 * 获取分词结果
	 * @param str
	 * @return
	 */
	public static List<String> getWords(String str){
		List<String> stringList=new ArrayList<> ();
		TokenStream stream = null;
		Analyzer analyzer=new ComplexAnalyzer (LuceneContext.class.getClassLoader ().getResource ("data").getPath ());
		try {
			stream = analyzer.tokenStream("content", new StringReader (str));
			CharTermAttribute attr = stream.addAttribute(CharTermAttribute.class);
			stream.reset();
			while(stream.incrementToken()){
				stringList.add(attr.toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(stream != null){
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return stringList;
	}


}
